﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Reflection;
using System.Text;
using Demo.History.Entities;
using VitCode.ObjectResolutionHelper;

namespace VitCode.ObjectSettingApp
{
    public class HistorySettingHelper:BaseHelper
    {
        public HistorySettingHelper()
        {
            InitInfo();
        }
        public string GetHisClassFileContext(Type baseObjType, string assName)
        {
            m_Checker.CheckClass(baseObjType);
            PropertyInfo[] pros = LookUpClassHelper.GetPros(baseObjType);
            var sb = new StringBuilder();
            NameValueCollection nvcMap = GetDbTypeMapping();
            var pId = baseObjType.GetProperty("Id");
            if (pId == null)
                throw new Exception("对象解析框架要求对象必需包含Id属性");
            sb.Append("using System;\r\n");
            sb.Append("using System.Collections;\r\n");
            sb.Append("using System.ComponentModel;\r\n");
            sb.Append("using VitCode.Castle.Entities;\r\n");
            sb.Append("using "+assName+".Entities;\r\n"); 
            sb.Append("using VitCode.Castle.Helper;\r\n");
            sb.Append("namespace "+LookUpClassHelper.ReplaceHistoryWord(assName)+".Entities\r\n");
            sb.Append("{\r\n");
            sb.Append("\t[Description(\""+LookUpClassHelper.GetOrMemoDesValue(baseObjType)+"历史记录\")]\r\n");
            sb.Append("\tpublic class " + baseObjType.Name + HistoryKeyInfo.LAST_STRING + " : BaseHistoryEntity\r\n");
            sb.Append("\t{\r\n");

            var hisObjType = typeof(BaseHistoryEntity);
            var baseObj = Activator.CreateInstance(baseObjType);
            var scNotCompareProNames = BaseHistoryEntity.GetNotCompareProNames(baseObj);
            var sc = new StringCollection{ID,HistoryKeyInfo.CURR_HIS_ID};
            foreach (var p in hisObjType.GetProperties())
            {
                sc.Add(p.Name);
            }

            foreach (PropertyInfo p in pros)
            {
                if (sc.Contains(p.Name)) continue;
                if (scNotCompareProNames.Contains(p.Name)) continue;
                sb.Append(GetMappingProContext(p, nvcMap));
            }

            sb.Append("\t}\r\n");
            sb.Append("}\r\n");

            return sb.ToString();
        }

        private string GetMappingProContext(PropertyInfo pro, NameValueCollection nvcTypeMapping)
        {
            var dbTypeName = nvcTypeMapping.Get(pro.PropertyType.ToString());
            var val = "";
            if (string.IsNullOrEmpty(dbTypeName))
            {
                var scChildKeyProNames = GetKeyProNames(pro.PropertyType);
                scChildKeyProNames.Add(HistoryKeyInfo.CURR_HIS_ID);
                var sb = new StringBuilder();
                foreach(string str in scChildKeyProNames)
                {
                    var childPro = pro.PropertyType.GetProperty(str);
                    if(childPro==null) continue;
                    sb.Append("\r\n");
                    sb.Append("\t\t[Description(\"" + LookUpClassHelper.GetOrMemoDesValue(pro) + LookUpClassHelper.GetOrMemoDesValue(childPro) + "\")]\r\n");
                    sb.Append("\t\tpublic virtual " + childPro.PropertyType.Name + " " + pro.Name + HistoryKeyInfo.PRO_FG + childPro.Name + " { get; set; }\r\n");
                }
                val = sb.ToString();
            }
            else
            {
                var strDes = LookUpClassHelper.GetOrMemoDesValue(pro);
                if (string.IsNullOrEmpty(strDes)) return "";
                val = "\r\n";
                val += "\t\t[Description(\"" + strDes + "\")]\r\n";
                val += "\t\tpublic virtual " + pro.PropertyType.Name + " "+pro.Name+" { get; set; }\r\n";
            }
            return val;
        }

        public StringCollection GetHisListSettingFileContext(string assName,string naming)
        {
            var sc = new StringCollection();
            ArrayList ts = LookUpClassHelper.GetTypes(assName, naming);
            sc.Add("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" +"<Setting>");
            foreach (Type objType in ts)
            {
                if (!objType.Name.EndsWith(HistoryKeyInfo.LAST_STRING))
                    continue;
                var sb = new StringBuilder();
                m_Checker.CheckClass(objType);
                var strDes = LookUpClassHelper.GetOrMemoDesValue(objType);
                
                var pId = objType.GetProperty(HistoryKeyInfo.H_ID);
                if (pId == null)
                    throw new Exception("对象解析框架要求对象必需包含Id属性");
                sb.Append("\t<" + objType.Name + " KeyProperty=\"" + HistoryKeyInfo.H_ID + "\" AssemblyName=\"" + assName + "\" NameSpace=\"" +
                          objType.Namespace + "\" Memo=\"" + strDes + "\">\r\n");
                sb.Append(GetSqlListNodeXml(objType, true));
                sb.Append("\t</" + objType.Name + ">");
                sc.Add(sb.ToString());
            }

            sc.Add(@"</Setting>");

            return sc;
        }
    }
}
